package com.songtech.base.universal.dao.api.util;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.songtech.base.universal.dao.beans.BeanParam;

/**
 * 通过反射将查询返回值赋值给对象
 */
public class HandleResult {
	/**
	 * 将一组查询返回值赋值到指定对象中
	 * @param resultMap
	 * @param tClazz
	 * @param listParams
	 * @return
	 */
	public List<?> handleResult(List<Map<String, Object>> resultMap, Class<?> tClazz, List<BeanParam> listParams){
		List<Object> list = new ArrayList<>();
		for(Map<String, Object> map : resultMap){
			list.add(this.handleResult(map, tClazz, listParams));
		}
		return list;
	}
	
	/**
	 * 将查询返回值赋值到指定对象中
	 * @param resultMap
	 * @param tClazz
	 * @param listParams
	 * @return
	 */
	public Object handleResult(Map<String, Object> resultMap, Class<?> tClazz, List<BeanParam> listParams) {
		if (resultMap == null) {
			return null;
		}
		Object t = null;
		try {
			t = tClazz.newInstance();
			// 实例化失败后抛出异常，不需要再进行赋值，所以放入try中
			for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
				String key = entry.getKey();
				Serializable val = (Serializable) entry.getValue();
				try {
					// 获取属性名
					key = this.getAttriName(listParams, key);
					this.setFileValue(t, tClazz, key, val);
				} catch (Exception e) {
					System.out.println("实例化Bean失败(" + tClazz.getName() + ")不能赋值到字段(" + key + ")!");
					e.printStackTrace();
				}
			}
		} catch (InstantiationException e) {
			System.out.println("实例化Bean失败(" + tClazz.getName() + ")!");
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			System.out.println("实例化Bean失败(" + tClazz.getName() + ")!");
			e.printStackTrace();
		}
		return t;
	}
	
	/**
	 * 通过反射给实体对象属性赋值
	 * @param object
	 * @param tClazz
	 * @param fieldName
	 * @param value
	 * @return
	 */
	private boolean setFileValue(Object object, Class<?> tClazz, String fieldName, Serializable value) {
		if (value != null) {
			try {
				Field field = tClazz.getDeclaredField(fieldName);
				Method method = tClazz.getMethod("set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1), field.getType());
				method.invoke(object, value);
				return true;
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			return false;
		}else{
			return true;
		}
	}
	
	/**
	 * 获取对应字段的属性名
	 * @param listParams 字段集合
	 * @param fieldName 字段名
	 * @return
	 */
	private String getAttriName(List<BeanParam> listParams, String fieldName){
		if(fieldName != null){
			for(BeanParam p : listParams){
				if(p != null && fieldName.equals(p.getFieldName())){
					return p.getAttriName();
				}
			}
		}
		return null;
	}
}
